/**
 * Copyright (C), 2015-2019, XXX有限公司
 * FileName: EvlAutotimer
 * Author:   xi
 * Date:     2019/7/9 9:51
 * Description:
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.supconit.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.supconit.entity.User;
import com.supconit.entity.UserTemp;
import com.supconit.service.IRankViewService;
import com.supconit.service.ITotalViewService;
import com.supconit.service.IUserService;
import com.supconit.service.IUserTempService;
import com.supconit.util.RedisUtils;
import com.supconit.util.WeixinUtil;
import io.netty.util.internal.StringUtil;
import lombok.extern.log4j.Log4j2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 〈一句话功能简述〉<br> 
 * 〈〉
 *
 * @author xi
 * @create 2019/7/9
 * @since 1.0.0
 */
@Component
@Log4j2
public class EvlAutoTimer {
    private static final Logger logger = LoggerFactory.getLogger(EvlAutoTimer.class);
    @Autowired
    RedisUtils redisUtils;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private IRankViewService rankService;
    @Autowired
    private ITotalViewService totalService;
    @Value("${wechat.appId}")
    private String appId;

    @Value("${wechat.appSecret}")
    private String appSecret;

    @Autowired
    private IUserService userService;
    @Autowired
    private IUserTempService userTempService;


    @Scheduled(cron = "0 0/10 * * * *")
    private void dualTotal(){
        // 设置当前的总量
        redisUtils.set("vote_total",totalService.list());
    }


    @Scheduled(cron = "0 0/30 * * * *")
    private void dualRank(){
        // 设置当前的排行
        redisUtils.set("vote_rank", rankService.list());
    }

    @Scheduled(cron = "0 0/6 * * * *")
    private void dualFollow(){
        logger.info("+++++++++++++get follows start++++++++++++++++" + new Date().toString());
        String token = redisUtils.get("token");
        if(StringUtil.isNullOrEmpty(token)){
            token =  WeixinUtil.getToken(appId, appSecret);
            if(StringUtils.isEmpty(token)){
                logger.info("+++++++++++++token is blank end++++++++++++++++");
                return;
            }
            redisUtils.set("token", token, 6840);
        }
        if(!StringUtil.isNullOrEmpty(token)){
            List<UserTemp> follows = new ArrayList<UserTemp>();
            follows = getFollows(follows,token, "");
            saveData(follows);
            dualUnionid();
        }

        logger.info("+++++++++++++get follows end++++++++++++++++"+new Date().toString());
    }

//    @Scheduled(cron = "0 0/10 * * * *")
    private void dualUnionid(){
        logger.info("+++++++++++++dualUnionid  start++++++++++++++++"+new Date().toString());
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(User::getDualFlag,0);
        List<User> list =userService.list(wrapper);
        List<User> newList =new ArrayList<>();
        String token = redisUtils.get("token");
        if(StringUtil.isNullOrEmpty(token)){
            token =  WeixinUtil.getToken(appId, appSecret);
            redisUtils.set("token",token,6840);
        }
        for(User user:list){
            String openId = user.getOpenId();
            JSONObject object = WeixinUtil.getUserInfo2(openId, token);
            String unionId = object.getString("unionid");
            if(!StringUtils.isEmpty(unionId)){
                user.setUnionid(unionId);
                user.setDualFlag(1);
                newList.add(user);
            }
        }
        if(newList!=null && newList.size()!=0){
            userService.updateBatchById(newList);
        }
        logger.info("+++++++++++++dualUnionid  end++++++++++++++++"+new Date().toString());
    }

    /**
     * 获取关注人员信息
     * @param follows
     * @param token
     * @param nextOpenId
     * @return
     */
    private List<UserTemp> getFollows(List follows,String token,String  nextOpenId){
        JSONObject obj =WeixinUtil.getOpenIds(token, nextOpenId);
        String data = obj.getString("data");
        JSONObject jsonObject=JSONObject.parseObject(data);
        JSONArray openIds = jsonObject.getJSONArray("openid");
//        List<UserTemp> list = new ArrayList<UserTemp>();
        for(int i=0;i<openIds.size();i++) {
            UserTemp newUser = new UserTemp();
            newUser.setOpenId(String.valueOf(openIds.get(i)));
            logger.info(String.valueOf(openIds.get(i)));
            follows.add(newUser);
        }
//        // 遍历插入数据库
//        List<String> list = JSONObject.parseArray(openIds.toJSONString(), String.class);
////        openIds.stream().forEach(jsonobejct->saveData(list));
//        follows.add(list);
        int count = obj.getInteger("count");
        nextOpenId =  obj.getString("next_openid");
        if(count==10000){
            getFollows(follows,token, nextOpenId);
        }
        return follows;
    }

    /**
     * 批量操作
     * @param list
     */
    private  void saveData(List<UserTemp> list) {
//        List<User> lst = userService.list();
//        List<String> openIdList = lst.stream().map(User::getOpenId).collect(Collectors.toList());
//        List<UserTemp> userTemps = new ArrayList<UserTemp>();
//        for(String openId:list){
//            UserTemp newUser = new UserTemp();
//            newUser.setOpenId(openId);
//            userTemps.add(newUser);
//        }
        userTempService.saveBatch(list);
        // 获取新增的
//        QueryWrapper<UserTemp> wrapper = new QueryWrapper<UserTemp>();
//        wrapper.lambda().in(UserTemp::getOpenId,openIdList);
        userTempService.dual_follow();


//        // 获取交集
//        QueryWrapper<User> wrapper = new QueryWrapper<>();
//        // 获取需要逻辑删除的A
//        List<String> difA = getDifferntBtoA(openIdList, list);
//        if(difA!=null && difA.size()!=0){
//            wrapper.lambda().in(User::getOpenId, difA);
//            List<User> alterUsers = userService.list(wrapper);
//            alterUsers.forEach(e -> {
//                e.setFlag(1);
//            } );
//            userService.updateBatchById(alterUsers);
//        }
//        // 获取新增的关注B
//        List<String> difB = getDifferntAtoB(openIdList,list);
//        List<User> users = difB.stream().map(openId -> {
//            User newUser = new User();
//            newUser.setOpenId(openId);
//            return newUser;
//        }).collect(Collectors.toList());
//        userService.saveBatch(users);
    }

    /**
     * 获取交集
     * @param listA
     * @param listB
     * @return
     */
    private List<String> getDifferntBtoA(List<String> listA,List<String> listB){

        LinkedList<String> linkedList= new LinkedList(listA);//大集合用linkedlist
        HashSet hashSet= new HashSet(listB);//小集合用hashset
        Iterator<String> iter = linkedList.iterator();//采用Iterator迭代器进行数据的操作
        List<String> myList = new ArrayList<String>();
        while(iter.hasNext()){
            String next = iter.next();
            if(hashSet.contains(next)){
                iter.remove();
            }else{
                myList.add(next);
            }
        }
        return myList;
//        List<String> intersectionList =listA.stream().filter(t->listB.contains(t)).collect(Collectors.toList());
//        System.out.println("集合的交集"+intersectionList);

//        List<String> ListARomoveB =listA.stream().filter(t-> !listB.contains(t)).collect(Collectors.toList());
//        System.out.println("a去除b的差集"+ ListARomoveB);
////
////        List<String> ListBRomoveA =listB.stream().filter(t-> !listA.contains(t)).collect(Collectors.toList());
////        System.out.println("b去除a的差集" + ListBRomoveA);
//        return ListARomoveB;
    }

    /**
     * 获取交集
     * @param listA
     * @param listB
     * @return
     */
    private List<String> getDifferntAtoB(List<String> listA,List<String> listB){

//        List<String> intersectionList =listA.stream().filter(t->listB.contains(t)).collect(Collectors.toList());
//        System.out.println("集合的交集"+intersectionList);

//        List<String> ListARomoveB =listA.stream().filter(t-> !listB.contains(t)).collect(Collectors.toList());
//        System.out.println("a去除b的差集"+ ListARomoveB);
        // 切割listA
        LinkedList<String> linkedList= new LinkedList(listB);//大集合用linkedlist
        HashSet hashSet= new HashSet(listA);//小集合用hashset
        Iterator<String> iter = linkedList.iterator();//采用Iterator迭代器进行数据的操作
        List<String> myList = new ArrayList<String>();
        while(iter.hasNext()){
            String next = iter.next();
            if(hashSet.contains(next)){
                iter.remove();
            }else{
                myList.add(next);
            }
        }


//        Lists.newLinkedList(iter)
//        List<String> myList = Lists.newArrayList(iter);
//        List<String> ListBRomoveA =listB.stream().iter(t-> !listA.contains(t)).collect(Collectors.toList());
//        System.out.println("b去除a的差集" + ListBRomoveA);
        return myList;
    }

}